<?php

namespace Celebrio\FileSystem;

use Celebrio\FileSystem\IVirtualFileSystem;
use Celebrio\FileSystem\VirtualFileSystem;
use Celebrio\FileSystem\DataFile;
use Celebrio\Core\ServiceProvider;
use Celebrio\Modules;

use Nette\Object;

/**
 *
 * @author Petr, pavel
 */
//TODO: add security control of api only for users applications!
class FileSystemApi extends Object implements IFileSystem {

    /**
     * @var IVirtualFileSystem
     */
    private $fileSystemManager;

    /**
     * Sets the attribute $userId according to the given parameter.
     *
     * @param \Nette\Web\User $user the object containing the user ID
     *        or the ID itself.
     */
    public function __construct($user = null) {
        $this->setFileSystemManager(new VirtualFileSystem($user));
    }

    public function getFileSystemManager() {
        return $this->fileSystemManager;
    }

    public function setFileSystemManager($fsm) {
        $this->fileSystemManager = $fsm;
    }

    public function load($urlFrom, $stream = false) {
        $dataFile = $this->makeDataFile($urlFrom);
        return $this->getFileSystemManager()->load($dataFile, $stream);
    }

    public function save($urlFrom, $data, $mimeType = null, $storageName = null) {
        if ($mimeType == null) {
            $mimeType = (empty($data) ? DataFile::DIR : "plain/text");
        }
        $dataFile = $this->makeDataFile($urlFrom);
        $dataFile->setData($data);
        $dataFile->setMimetypeText($mimeType);
        if($storageName == null) {
            $storage = ServiceProvider::getAllServiceNames(Modules::FS_DRIVERS);
            $dataFile->setFstorageName($storage[0]::NAME);
        } else {
            $dataFile->setFstorageName($storageName);
        }
        $this->getFileSystemManager()->save($dataFile);
    }

    public function getFileInfo($urlFrom) {
        $dataFile = $this->makeDataFile($urlFrom);
        return $this->getFileSystemManager()->getFileInfo($dataFile);
    }

    public function copy($urlFrom, $urlTo, $rewrite) {
        $boolRewrite = $this->checkRewrite($rewrite);
        $dataFileFrom = $this->makeDataFile($urlFrom);
        $dataFileTo = $this->makeDataFile($urlTo);
        $this->getFileSystemManager()->copy($dataFileFrom, $dataFileTo, $rewrite);
    }

    public function move($urlFrom, $urlTo, $rewrite) {
        $boolRewrite = $this->checkRewrite($rewrite);
        $dataFileFrom = $this->makeDataFile($urlFrom);
        $dataFileTo = $this->makeDataFile($urlTo);
        $this->getFileSystemManager()->move($dataFileFrom, $dataFileTo, $rewrite);
    }

    public function delete($urlFrom) {
        $dataFile = $this->makeDataFile($urlFrom);
        $this->getFileSystemManager()->delete($dataFile);
    }

    private function makeDataFile($url) {
        $url = rtrim($url, '/');
        if (empty($url)) {
            $fileName = "/";
            $fileUrl = NULL;
        } else {
            $lastOccur = strrpos($url, '/') + 1;
            $fileUrl = substr($url, 0, $lastOccur);
            $fileName = substr($url, $lastOccur);
        }
        $dataFile = new DataFile($fileName, $fileUrl);
        return $dataFile;
    }

    /**
     * just because of PHP crappy typecasting
     *
     * @param mixed $rewrite
     * @return boolean
     */
    private function checkRewrite($rewrite) {
        if (is_null($rewrite)) {
            return false;
        } elseif (is_bool($rewrite)) {
            return $rewrite;
        } elseif (is_string($rewrite)) {
            if ($rewrite === "true" || $rewrite == "1") {
                return true;
            } elseif ($rewrite === "false" || $rewrite == "0") {
                return false;
            }
        }
        throw new \InvalidArgumentException("Rewrite is not boolean!");
    }

}